package secret

import (
	"fmt"

	"gitee.com/micro-plat/sas/sas/modules/const/conf"
	"gitee.com/micro-plat/sas/sas/modules/const/enum"
	"gitee.com/micro-plat/sas/sas/modules/const/models"
	"gitee.com/micro-plat/sas/sas/modules/const/sqls"
	"gitee.com/micro-plat/sas/sas/modules/util"
	"github.com/micro-plat/hydra"
	"github.com/micro-plat/lib4go/types"
)

//DBSecret 对象
type DBSecret struct{}

//NewDBSecret 创建对象
func NewDBSecret() *DBSecret {
	return &DBSecret{}
}

// GetPermission 获取用户加密权限信息
func (s *DBSecret) GetPermission(euid string) (types.XMap, error) {
	db := hydra.C.DB().GetRegularDB(conf.DBName)

	rows, err := db.Query(sqls.GetPermissionByOutID, map[string]interface{}{
		"euid": euid,
	})
	if err != nil {
		return nil, fmt.Errorf(`获取用户加密权限信息出错:%v`, err)
	}

	if rows.IsEmpty() {
		return nil, nil
	}
	return rows[0], nil
}

func (s *DBSecret) updateSecret(uid, secret string, sType int, expireTime string) (err error) {
	encrypt, err := util.AESEncrypt(secret, util.MD5(uid))
	if err != nil {
		return fmt.Errorf("密钥加密出错:%v", err)
	}

	db := hydra.C.DB().GetRegularDB(conf.DBName)
	row, err := db.Execute(sqls.UpdateSecretSQL(enum.GetNameByValue(sType)), map[string]interface{}{
		"uid":         uid,
		"secret":      encrypt,
		"expire_time": expireTime,
	})
	if err != nil || row != 1 {
		err = fmt.Errorf(`更新用户密钥出错(row:%d):%v`, row, err)
		return
	}

	return
}
func (s *DBSecret) addCertSecret(euid string, item *models.Item) (uid string, err error) {
	db := hydra.C.DB().GetRegularDB(conf.DBName)
	trans, err := db.Begin()
	if err != nil {
		err = fmt.Errorf("addCertSecret,开启事务失败: %v", err)
		return
	}
	id, row, err := trans.Executes(sqls.InsetNewData, map[string]interface{}{
		"euid":   euid,
		"status": enum.Cert,
	})
	if err != nil || row != 1 {
		trans.Rollback()
		err = fmt.Errorf(`添加用户数据及Cert密钥出错(row:%d):%v`, row, err)
		return
	}
	uid = types.GetString(id)

	mapData := types.XMap{
		"mer_cert":  item.MerchantCert,
		"spl_cert":  item.SupplierCert,
		"root_cert": item.RootCert,
		"cert_key":  item.CertKey,
	}

	valMap := types.XMap{}
	for k, tv := range mapData {
		v := types.GetString(tv)
		if v == "" {
			continue
		}
		valMap[k], err = util.AESEncrypt(v, util.MD5(uid))
		if err != nil {
			trans.Rollback()
			return uid, fmt.Errorf("addCertSecret %s加密出错:%+v", k, err)
		}
	}
	valMap["uid"] = uid
	valMap["expire_time"] = item.ExpireTime

	row, err = trans.Execute(sqls.UpdateCertSecret, valMap)
	if err != nil || row != 1 {
		trans.Rollback()
		err = fmt.Errorf(`更新用户Cert密钥出错(row:%d):%v`, row, err)
		return
	}
	trans.Commit()
	return uid, err
}
func (s *DBSecret) updateCertSecret(uid string, item *models.Item) (err error) {

	mapData := types.XMap{
		"mer_cert":  item.MerchantCert,
		"spl_cert":  item.SupplierCert,
		"root_cert": item.RootCert,
		"cert_key":  item.CertKey,
	}

	valMap := types.XMap{}
	for k, tv := range mapData {
		v := types.GetString(tv)
		if v == "" {
			continue
		}
		valMap[k], err = util.AESEncrypt(v, util.MD5(uid))
		if err != nil {
			return fmt.Errorf("updateCertSecret %s加密出错:%+v", k, err)
		}
	}
	valMap["uid"] = uid
	valMap["expire_time"] = item.ExpireTime
	valMap["status"] = enum.Cert
	db := hydra.C.DB().GetRegularDB(conf.DBName)
	row, err := db.Execute(sqls.UpdateCertSecret, valMap)
	if err != nil || row != 1 {
		err = fmt.Errorf(`更新用户Cert密钥出错(row:%d):%v`, row, err)
		return
	}

	return
}

func (s *DBSecret) addDataAndSecret(euid, secret string, sType int) (uid string, err error) {
	db := hydra.C.DB().GetRegularDB(conf.DBName)

	trans, err := db.Begin()
	if err != nil {
		err = fmt.Errorf("addDataAndSecret,开启事务失败: %v", err)
		return
	}

	id, row, err := trans.Executes(sqls.InsetNewData, map[string]interface{}{
		"euid":   euid,
		"status": sType,
	})
	if err != nil || row != 1 {
		trans.Rollback()
		err = fmt.Errorf(`添加用户数据及密钥出错(row:%d):err:%v`, row, err)
		return
	}

	uid = types.GetString(id)

	encrypt, err := util.AESEncrypt(secret, util.MD5(uid))
	if err != nil {
		trans.Rollback()
		err = fmt.Errorf("addDataAndSecret 密钥加密出错:%v", err)
		return
	}

	row, err = trans.Execute(sqls.UpdateSecretSQL(enum.GetNameByValue(sType)), map[string]interface{}{
		"uid":    uid,
		"secret": encrypt,
	})
	if err != nil || row != 1 {
		trans.Rollback()
		err = fmt.Errorf(`更新用户密钥出错(row:%d):%v`, row, err)
		return
	}

	trans.Commit()
	return
}

func (s *DBSecret) addSecret(uid, secret string, sType int) (err error) {
	encrypt, err := util.AESEncrypt(secret, util.MD5(uid))
	if err != nil {
		err = fmt.Errorf("addSecret 密钥加密出错:%v", err)
		return
	}

	db := hydra.C.DB().GetRegularDB(conf.DBName)
	row, err := db.Execute(sqls.AddSecretSQL(enum.GetNameByValue(sType)), map[string]interface{}{
		"uid":    uid,
		"secret": encrypt,
		"status": sType,
	})
	if err != nil || row != 1 {
		err = fmt.Errorf(`添加用户密钥出错(row:%d):%v`, row, err)
		return
	}

	return
}

func (s *DBSecret) addRSASecret(euid, pubSecret, priSecret, pkcsType string, bits int, expire string) (uid string, err error) {
	trans, err := hydra.C.DB().GetRegularDB(conf.DBName).Begin()
	if err != nil {
		err = fmt.Errorf("addDataAndSecret,开启事务失败: %v", err)
		return
	}

	id, row, err := trans.Executes(sqls.InsetNewData, map[string]interface{}{
		"euid":   euid,
		"status": enum.RSA,
	})
	if err != nil || row != 1 {
		trans.Rollback()
		err = fmt.Errorf(`添加用户数据及RSA密钥出错(row:%d):%v`, row, err)
		return
	}
	uid = types.GetString(id)

	pubEncrypt, err := util.AESEncrypt(pubSecret, util.MD5(uid))
	if err != nil {
		trans.Rollback()
		err = fmt.Errorf("addDataAndRSASecret RSA公钥加密出错:%v", err)
		return
	}
	priEncrypt, err := util.AESEncrypt(priSecret, util.MD5(uid))
	if err != nil {
		trans.Rollback()
		err = fmt.Errorf("addDataAndRSASecret RSA私钥加密出错:%v", err)
		return
	}

	row, err = trans.Execute(sqls.UpdateRSASecret, map[string]interface{}{
		"uid":                uid,
		"rsa_public_secret":  pubEncrypt,
		"rsa_private_secret": priEncrypt,
		"rsa_bits":           bits,
		"rsa_type":           pkcsType,
		"expire_time":        expire,
	})
	if err != nil || row != 1 {
		trans.Rollback()
		err = fmt.Errorf(`更新用户RSA密钥出错(row:%d):%v`, row, err)
		return
	}

	trans.Commit()
	return
}

func (s *DBSecret) updateRSASecret(uid, pubSecret, priSecret, pkcsType string, bits int, expire string) (err error) {
	pubEncrypt, err := util.AESEncrypt(pubSecret, util.MD5(uid))
	if err != nil {
		err = fmt.Errorf("updateRSASecret RSA公钥加密出错:%v", err)
		return
	}
	priEncrypt, err := util.AESEncrypt(priSecret, util.MD5(uid))
	if err != nil {
		err = fmt.Errorf("updateRSASecret RSA私钥加密出错:%v", err)
		return
	}

	db := hydra.C.DB().GetRegularDB(conf.DBName)
	row, err := db.Execute(sqls.UpdateRSASecret, map[string]interface{}{
		"uid":                uid,
		"rsa_public_secret":  pubEncrypt,
		"rsa_private_secret": priEncrypt,
		"rsa_type":           pkcsType,
		"rsa_bits":           bits,
		"status":             enum.RSA,
		"expire_time":        expire,
	})
	if err != nil || row != 1 {
		err = fmt.Errorf(`添加用户RSA密钥出错(row:%d):%v`, row, err)
		return
	}

	return
}

func (s *DBSecret) enableSecret(uid string, sType int) (err error) {
	db := hydra.C.DB().GetRegularDB(conf.DBName)
	row, err := db.Execute(sqls.EnableSecret, map[string]interface{}{
		"uid":    uid,
		"status": sType,
	})
	if err != nil || row != 1 {
		err = fmt.Errorf(`启用用户密钥出错(row:%d):%v`, row, err)
		return
	}

	return
}

func (s *DBSecret) disableSecret(uid string, sType int) (err error) {
	db := hydra.C.DB().GetRegularDB(conf.DBName)
	row, err := db.Execute(sqls.DisableSecret, map[string]interface{}{
		"uid":    uid,
		"status": sType,
	})
	if err != nil || row != 1 {
		err = fmt.Errorf(`禁用用户密钥出错(row:%d):%v`, row, err)
		return
	}

	return
}
